package com.yiren.dbaa.module.practice_set.carmodel.view.activity;

import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.view.KeyEvent;
import android.view.View;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.RadioGroup;
import android.widget.TextView;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.yiren.backstage.currency.bean.GpsInfoBean;
import com.yiren.backstage.currency.bean.PointExBean;
import com.yiren.backstage.currency.entity.CarModelEntity;
import com.yiren.dbaa.R;
import com.yiren.dbaa.activity.BaseActivity;
import com.yiren.dbaa.module.practice_set.carmodel.contract.CarModelCollectContract;
import com.yiren.dbaa.module.practice_set.carmodel.presenter.CarModelCollectPresenter;
import com.yiren.dbaa.module.practice_set.carmodel.view.CarMapView;
import com.yiren.dbaa.module.practice_set.carmodel.view.adapter.CarModelPointAdapter;
import com.yiren.dbaa.util.JtsUtils;
import com.yiren.dbaa.view.dialog.CustomDialog;
import com.yiren.dbaa.view.dialog.LoadDialog;
import com.yiren.dbaa.view.toast.MessageBox;

import org.apache.commons.lang.StringUtils;

import java.util.ArrayList;
import java.util.List;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;

/**
 * @author lwb
 * @date :2021/11/26 9:53
 * @description: 车辆模型描点采集
 */
public class CarModelCollectActivity extends BaseActivity implements CarModelCollectContract.View, CarModelPointAdapter.OnPointActionListener {

    @BindView(R.id.tv_front_antenna)
    TextView tvFrontAntenna;   //前天线
    @BindView(R.id.tv_after_antenna)
    TextView tvAfterAntenna;   //后天线
    @BindView(R.id.tv_distance_x)
    TextView tvDistanceX;      //东坐标
    @BindView(R.id.tv_distance_y)
    TextView tvDistanceY;      //北坐标
    @BindView(R.id.rg_collect)
    RadioGroup rgCollect;
    @BindView(R.id.ll_co_sample)
    LinearLayout llCoSample;   //采集示意
    @BindView(R.id.ll_co_model)
    LinearLayout llCoModel;    //采集模型
    @BindView(R.id.car_map_view)
    CarMapView carMapView;
    @BindView(R.id.cb_follow_location)
    CheckBox cbFollowLocation; //跟随定位
    @BindView(R.id.tv_unit)
    TextView tvUnit;
    @BindView(R.id.tv_point_action)
    TextView tvPointAction;    //显示或隐藏点位
    @BindView(R.id.tv_point_a)
    TextView tvPointA;         //点A
    @BindView(R.id.tv_point_b)
    TextView tvPointB;         //点B
    @BindView(R.id.tv_point_c)
    TextView tvPointC;         //点C
    @BindView(R.id.tv_point_d)
    TextView tvPointD;         //点D
    @BindView(R.id.tv_car_type)
    TextView tvCarType;        //正在采集车型
    @BindView(R.id.et_chgpy_radius)
    EditText etChgpyRadius;    //测绘杆偏移半径
    @BindView(R.id.lv_car_point)
    ListView lvCarPoints;      //采集点位列表

    private Intent intent;
    /*** 当前车辆模型 */
    private CarModelEntity carModel;
    private List<PointExBean> carModelPoints;
    private Handler handler;
    private GpsInfoBean gpsInfo;
    /*** 半径 */
    float radius = 0;
    /*** 车辆模型点位适配器 */
    private CarModelPointAdapter myAdapter;

    /*** 状态信息线程类 */
    private Runnable stateInfoRunnable;
    private JtsUtils jtsUtils;
    private PointExBean pointA;
    private PointExBean pointB;
    private PointExBean pointC;
    private PointExBean pointD;
    private CarModelCollectContract.Presenter carModelCollectPresenter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_car_model_collect);
        ButterKnife.bind(this);
        initData();
        initListener();
        refresh();
    }

    private void initData() {
        intent = getIntent();
        carModel = (CarModelEntity) intent.getSerializableExtra("carModel");
        carModelPoints = new Gson().fromJson(carModel.getPoints(), new TypeToken<List<PointExBean>>() {
        }.getType());
        if (null == carModelPoints) {
            carModelPoints = new ArrayList<>();
            for (int i = 0; i < 33; i++) {
                carModelPoints.add(null);
            }
        }
        tvCarType.setText("正在采集：" + carModel.getName());
        tvUnit.setText(carMapView.getAccuracyText());
        handler = new Handler();
        jtsUtils = new JtsUtils();
        carModelCollectPresenter = new CarModelCollectPresenter(this);
        myAdapter = new CarModelPointAdapter(this, carModelPoints, carModelCollectPresenter, this);
        lvCarPoints.setAdapter(myAdapter);
    }

    private void initListener() {
        rgCollect.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(RadioGroup group, int checkedId) {
                switch (checkedId) {
                    case R.id.rb_sample:
                        llCoSample.setVisibility(View.VISIBLE);
                        llCoModel.setVisibility(View.GONE);
                        break;
                    case R.id.rb_model:
                        llCoSample.setVisibility(View.GONE);
                        llCoModel.setVisibility(View.VISIBLE);
                        carMapView.setCarModelPoints(carModelPoints);
                        break;
                }
            }
        });
        cbFollowLocation.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                cbFollowLocation.setChecked(isChecked);
                carMapView.setFollow(isChecked);
            }
        });
    }

    @OnClick({R.id.tv_point_action, R.id.tv_point_a, R.id.tv_point_b, R.id.tv_point_c, R.id.tv_point_d, R.id.btn_param_init, R.id.btn_save_car, R.id.iv_scale_big, R.id.iv_scale_small})
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.tv_point_action:   //显示或隐藏点位
                carMapView.setShowPoint(!carMapView.isShowPoint());
                tvPointAction.setText(carMapView.isShowPoint() ? "隐\n藏\n点\n位" : "显\n示\n点\n位");
                break;
            case R.id.tv_point_a:   //点a
                if (carModelCollectPresenter.isCanCollectABCD(carModelPoints)) {
                    if (gpsInfo.getStatusPosition() == 3) {
                        pointA = new PointExBean();
                        pointA.setPoint(gpsInfo.getDistanceX(), gpsInfo.getDistanceY());
                        carMapView.setFramePoint(0, pointA);
                        tvPointA.setText("校准A");
                        refreshMarginShow();
                    } else {
                        MessageBox.show(this, "当前定位座标不是固定解");
                    }
                } else {
                    MessageBox.show(this, "先进行参数初始化才能采集");
                }
                break;
            case R.id.tv_point_b:   //点b
                if (carModelCollectPresenter.isCanCollectABCD(carModelPoints)) {
                    if (gpsInfo.getStatusPosition() == 3) {
                        pointB = new PointExBean();
                        pointB.setPoint(gpsInfo.getDistanceX(), gpsInfo.getDistanceY());
                        carMapView.setFramePoint(1, pointB);
                        tvPointB.setText("校准B");
                        refreshMarginShow();
                    } else {
                        MessageBox.show(this, "当前定位座标不是固定解");
                    }
                } else {
                    MessageBox.show(this, "先进行参数初始化才能采集");
                }
                break;
            case R.id.tv_point_c:   //点c
                if (carModelCollectPresenter.isCanCollectABCD(carModelPoints)) {
                    if (gpsInfo.getStatusPosition() == 3) {
                        pointC = new PointExBean();
                        pointC.setPoint(gpsInfo.getDistanceX(), gpsInfo.getDistanceY());
                        carMapView.setFramePoint(2, pointC);
                        tvPointC.setText("校准C");
                        refreshMarginShow();
                    } else {
                        MessageBox.show(this, "当前定位座标不是固定解");
                    }
                } else {
                    MessageBox.show(this, "先进行参数初始化才能采集");
                }
                break;
            case R.id.tv_point_d:   //点d
                if (carModelCollectPresenter.isCanCollectABCD(carModelPoints)) {
                    if (gpsInfo.getStatusPosition() == 3) {
                        pointD = new PointExBean();
                        pointD.setPoint(gpsInfo.getDistanceX(), gpsInfo.getDistanceY());
                        carMapView.setFramePoint(3, pointD);
                        tvPointD.setText("校准D");
                        refreshMarginShow();
                    } else {
                        MessageBox.show(this, "当前定位座标不是固定解");
                    }
                } else {
                    MessageBox.show(this, "先进行参数初始化才能采集");
                }
                break;
            case R.id.btn_param_init: //参数初始化
                carModelCollectPresenter.initParameter(carModelPoints, this);
                break;
            case R.id.btn_save_car: //保存车型
                saveCarModel();
                break;
            case R.id.iv_scale_big: //放大
                carMapView.setAccuracy(false);
                tvUnit.setText(carMapView.getAccuracyText());
                break;
            case R.id.iv_scale_small: //缩小
                carMapView.setAccuracy(true);
                tvUnit.setText(carMapView.getAccuracyText());
                break;
        }
    }

    private void refresh() {
        stateInfoRunnable = new Runnable() {
            @Override
            public void run() {
                gpsInfo = GpsInfoBean.getInstance();
                if (null != gpsInfo) {
                    tvFrontAntenna.setText("前天线:" + gpsInfo.getStatusDirection() + "/" + gpsInfo.getSatelliteFront());
                    tvAfterAntenna.setText("后天线:" + gpsInfo.getStatusPosition() + "/" + gpsInfo.getSatelliteBack());
                    tvDistanceX.setText("东坐标:" + gpsInfo.getDistanceX());
                    tvDistanceY.setText("北坐标:" + gpsInfo.getDistanceY());
                    carMapView.setCurrentPoint(gpsInfo.getDistanceX(), gpsInfo.getDistanceY(), gpsInfo.getStatusPosition());
                    carMapView.setAngle(gpsInfo.getAzimuth());
                }
                handler.postDelayed(this, 100);
            }
        };
        stateInfoRunnable.run();
    }

    @Override
    public void showZeroPointDialog() {
        CustomDialog.Builder builder = new CustomDialog.Builder(this);
        builder.setTitle("温馨提示");
        builder.setMessage("修改车型前需要将后采集天线放在车的零点位置,确定已经放好?");
        builder.setPositiveButton("确定", (dialog, which) -> {
            dialog.dismiss();
            if (gpsInfo.getStatusDirection() != 3) {
                MessageBox.show(this, "前天线定位失败,将后天线放置车顶后等待几分钟，如果还不能定位断电重启移动基站主机盒！");
                return;
            }
            carModelCollectPresenter.recoverCarModelPoint(carModelPoints, gpsInfo);
            carModelCollectPresenter.recoverPointABCD(pointA, 0, gpsInfo, carMapView);
            carModelCollectPresenter.recoverPointABCD(pointB, 1, gpsInfo, carMapView);
            carModelCollectPresenter.recoverPointABCD(pointC, 2, gpsInfo, carMapView);
            carModelCollectPresenter.recoverPointABCD(pointD, 3, gpsInfo, carMapView);
            refreshMarginShow();
            myAdapter.notifyDataSetChanged();
        });
        builder.setNegativeButton("取消", (dialog, which) -> dialog.dismiss());
        builder.create().show();
    }

    @Override
    public void refreshMargin() {
        refreshMarginShow();
    }

    @Override
    public void onPointCollect(int position) {
        if (gpsInfo.getStatusPosition() == 3) {
            if (position == 0) {
                if (!carModelCollectPresenter.isPointCollect(carModelPoints)) {
                    MessageBox.show(this, "0点最后采集，请先采集完车辆其它点位！");
                    return;
                }
            }
            PointExBean point = carModelPoints.get(position);
            if (null == point) {
                point = new PointExBean();
            } else {
                PointExBean zeroPoint = carModelPoints.get(0);
                if (null != zeroPoint) {
                    if (zeroPoint.getX() == 0 && zeroPoint.getY() == 0) {
                        MessageBox.show(this, "请先点击‘参数初始化’后再校准点位");
                        return;
                    }
                }
            }
            point.setPoint(gpsInfo.getDistanceX(), gpsInfo.getDistanceY());
            carModelPoints.set(position, point);
            //更新车辆点位
            myAdapter.notifyDataSetChanged();
            carMapView.setCarModelPoints(carModelPoints);
            carMapView.setSelectedIndex(position);
            if (position == 1 || position == 13 || position == 25 || position == 27 || position == 29 || position == 31) {
                refreshMarginShow();
            }
        } else {
            MessageBox.show(this, "当前定位座标不是固定解");
        }
    }

    /**
     * 保存车辆模型
     */
    private void saveCarModel() {
        PointExBean originPointEx = carModelPoints.get(0);
        if (null != originPointEx) {
            if (originPointEx.getX() == 0 && originPointEx.getY() == 0) {
                MessageBox.show(this, "已保存！");
                return;
            }
        } else {
            MessageBox.show(this, "0点未采集，请先采集0点！");
            return;
        }
        String etRadius = etChgpyRadius.getText().toString().trim();
        if (StringUtils.isNotEmpty(etRadius)) {
            radius = Float.parseFloat(etRadius);
            if (radius > 10) {
                MessageBox.show(this, "半径值不能超过10");
                return;
            }
            radius /= 100.f;
        }
        CustomDialog.Builder builderS = new CustomDialog.Builder(this);
        builderS.setTitle("温馨提示");
        builderS.setMessage("保存车型前需要将后采集天线放在车的零点位置,确定已经放好?");
        builderS.setPositiveButton("确定", (dialog, which) -> {
            dialog.dismiss();
            if (gpsInfo.getStatusDirection() != 3) {
                MessageBox.show(this, "前天线定位失败,将后天线放置车顶后等待几分钟，如果还不能定位断电重启移动基站主机盒！");
                return;
            }
            LoadDialog.show(this, "正在保存，请稍后...", false);
            new Thread(() -> {
                carModelCollectPresenter.fixPointABCD(originPointEx, pointA, 0, gpsInfo, carMapView);
                carModelCollectPresenter.fixPointABCD(originPointEx, pointB, 1, gpsInfo, carMapView);
                carModelCollectPresenter.fixPointABCD(originPointEx, pointC, 2, gpsInfo, carMapView);
                carModelCollectPresenter.fixPointABCD(originPointEx, pointD, 3, gpsInfo, carMapView);
                carModelCollectPresenter.fixCarModelPoint(carModelPoints, radius, gpsInfo, carModel);
                refreshMarginShow();
                runOnUiThread(() -> {
                    LoadDialog.dismiss(this);
                    MessageBox.show(this, "保存成功！");
                    etChgpyRadius.setText("");
                    myAdapter.notifyDataSetChanged();
                });
            }).start();
        });
        builderS.setNegativeButton("取消", (dialog, which) -> dialog.dismiss());
        builderS.create().show();
    }

    /**
     * 刷新边距显示(是否显示1,13,25,27,29,31的边距)
     */
    private void refreshMarginShow() {
        int[] showMargin = new int[]{0, 0, 0, 0, 0, 0};
        if (null != carModelPoints && carModelPoints.size() > 0) {
            if (null != pointA && null != pointB && null != carModelPoints.get(1)) {
                PointExBean pointEx = carModelPoints.get(1);
                if (null != pointEx) {
                    showMargin[0] = (int) (jtsUtils.distanceGeo(jtsUtils.createGeomPoint(pointEx), jtsUtils.createLine(pointA, pointB)) * 100);
                }
            }
            if (null != pointC && null != pointD && null != carModelPoints.get(13)) {
                PointExBean pointEx = carModelPoints.get(13);
                if (null != pointEx) {
                    showMargin[1] = (int) (jtsUtils.distanceGeo(jtsUtils.createGeomPoint(pointEx), jtsUtils.createLine(pointC, pointD)) * 100);
                }
            }
            if (null != pointA && null != pointD && null != carModelPoints.get(25)) {
                PointExBean pointEx = carModelPoints.get(25);
                if (null != pointEx) {
                    showMargin[2] = (int) (jtsUtils.distanceGeo(jtsUtils.createGeomPoint(pointEx), jtsUtils.createLine(pointA, pointD)) * 100);
                }
            }
            if (null != pointB && null != pointC && null != carModelPoints.get(27)) {
                PointExBean pointEx = carModelPoints.get(27);
                if (null != pointEx) {
                    showMargin[3] = (int) (jtsUtils.distanceGeo(jtsUtils.createGeomPoint(pointEx), jtsUtils.createLine(pointB, pointC)) * 100);
                }
            }
            if (null != pointA && null != pointD && null != carModelPoints.get(29)) {
                PointExBean pointEx = carModelPoints.get(29);
                if (null != pointEx) {
                    showMargin[4] = (int) (jtsUtils.distanceGeo(jtsUtils.createGeomPoint(pointEx), jtsUtils.createLine(pointA, pointD)) * 100);
                }
            }
            if (null != pointB && null != pointC && null != carModelPoints.get(31)) {
                PointExBean pointEx = carModelPoints.get(31);
                if (null != pointEx) {
                    showMargin[5] = (int) (jtsUtils.distanceGeo(jtsUtils.createGeomPoint(pointEx), jtsUtils.createLine(pointB, pointC)) * 100);
                }
            }
            carMapView.setShowMargin(showMargin);
        }
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            if (carModelCollectPresenter.isCanRecover(carModelPoints)) {
                finish();
            } else {
                CustomDialog.Builder builder = new CustomDialog.Builder(this);
                builder.setTitle("提示");
                builder.setCanceled(false);
                builder.setMessage("数据暂未保存,请确认是否保存?");
                builder.setPositiveButton("是", (dialog, which) -> {
                    dialog.dismiss();
                    saveCarModel();
                });
                builder.setNegativeButton("否", (dialog, which) -> {
                    dialog.dismiss();
                    finish();
                });
                builder.create().show();
                return true;
            }
        }
        return super.onKeyDown(keyCode, event);
    }

    @Override
    protected void onDestroy() {
        handler.removeCallbacks(stateInfoRunnable);
        super.onDestroy();
    }

}